home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
polyview
/
polyvw31.lha
/
Polyview3.1
/
new
/
pvaction.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-23
|
7KB
|
220 lines
/*****************************************************************************
* NCSA Polyview 3.0 *
* *
* Version 3 changes and additions by Marc Andreessen. *
* Version 2 by Brian Calvert. *
* *
* Software Development Group *
* National Center for Supercomputing Applications *
* University of Illinois at Urbana-Champaign *
* *
* This is BETA release software. As such it may contain software bugs and *
* exhibit inconsistencies. *
* *
* Please send bug reports to polyview@ncsa.uiuc.edu. *
* *
* Copyright (c) 1992 The Board of Trustees of the University of Illinois. *
* *
* Permission to use, copy, and modify this software and its *
* documentation for educational, research, and non-profit purposes is *
* hereby granted, provided that the above copyright notice, the original *
* authors names, and this permission notice appear in all such copies. *
* Any distribution of this software requires the explicit and written *
* authorization of the authors. *
* *
* The University of Illinois makes no representations about the *
* suitability of this software for any purpose. It is provided "as is" *
* without warranty of any kind. *
*****************************************************************************/
/* $Header: /usr3/people/gbourhis/pv3/new/RCS/pvaction.c,v 1.1 92/09/18 10:55:26 marca Exp $ */
#ifdef RCSLOG
$Log: pvaction.c,v $
* Revision 1.1 92/09/18 10:55:26 marca
* Initial revision
*
#endif
#include "pv.h"
action_t *new_action (state_t *state, int (*action_fn)(), int argc,
arg_t arg[MAXACTIONARGS], int steps)
{
action_t *new;
if (state->action_free == NULL)
{
/* If no action exists in the free list, make one. */
new = (action_t *) PVMALLOC(sizeof(action_t));
}
else
{
/* Get an action from the action_free list, if one exists. */
new = state->action_free;
state->action_free = new->next_serial;
}
/* Internal check. */
assert (new != NULL);
/* Make sure there is a valid pointer before loading the record. */
/* Fill the action fields with values specified. */
new->action_fn = action_fn;
new->argc = argc;
new->count = steps;
new->countdown = steps;
while (--argc >= 0)
new->arg[argc] = arg[argc];
return new;
}
action_t *add_action (state_t *state, int (*action_fn)(), int argc,
arg_t arg[MAXACTIONARGS],
int steps, int global, int at_current)
{
action_t *new;
action_t *insert;
new = new_action(state, action_fn, argc, arg, steps);
if (new != NULL) {
/* Make sure there is a valid pointer before loading the record. */
/* Fill the action fields with values specified. */
new->action_fn = action_fn;
new->argc = argc;
new->count = steps;
new->countdown = steps;
new->global = global;
while (--argc >= 0)
new->arg[argc] = arg[argc];
if (at_current == TRUE)
{
/* If adding at the current point, then get a pointer to */
/* the head of the list. */
insert = state->action_head;
}
else
{
/* If adding at the end of the list, then get a pointer to */
/* the tail. */
insert = state->action_tail;
}
if (insert == NULL)
{
/* This is the only action in the list. As a result, */
/* it is both the head and the tail. */
state->action_head = state->action_tail = new;
/* This action has no relatives. */
new->next_serial = NULL;
}
else
{
/* Add the new action serially after the insert */
/* point. */
new->next_serial = insert->next_serial;
insert->next_serial = new;
/* If the new action was inserted (serially) */
/* after the tail of the list, update the */
/* tail pointer. */
if (insert == state->action_tail)
state->action_tail = new;
}
}
/* Return value is the pointer to the new record. */
return new;
}
action_t *next_ser_action (state_t *state, action_t *current)
{
if (current == NULL)
{
/* If there are no current actions, there is not a next serial */
/* action. */
return NULL;
}
if (current->countdown <= 0)
{
/* If the countdown is zero, remove the action from the list. */
/* Adjust the head of the list. */
state->action_head = current->next_serial;
/* Free up the old action record for reuse. */
free_action(state, current);
/* Get the new current pointer. */
current = state->action_head;
}
if (current == NULL)
{
/* If there is no next serial action, there are no members in */
/* the list any more. */
state->action_head =
state->action_tail = NULL;
}
else
{
/* If there is still a "current" action, its count should be */
/* marked down. */
(current->countdown)--;
}
return current;
}
int free_action (state_t *state, action_t *action)
{
#if 0
/* This isn't done since 'move camera' actions get freed twice
in some cases; dunno why; code is screwed up; not my fault. */
/* Free the fields of the args. */
while (--(action->argc) >= 0) {
PVFREE(action->arg[action->argc].description);
PVFREE(action->arg[action->argc].value);
}
#endif
/* Add the action structure to the system's free list of old actions. */
action->next_serial = state->action_free;
state->action_free = action;
return ST_OKAY;
}
int do_action (state_t *state, action_t *action)
{
window_t *win;
int i;
assert (action != NULL);
assert (action->action_fn != NULL);
if (action->global)
{
return((*(action->action_fn))(state, action, NULL));
}
else
{
FOR_EACH_ACTIVE(win, state)
{
(*(action->action_fn))(state, action, win);
}
return ST_OKAY;
}
}